/**
  ******************************************************************************
  * File Name          : lorabsp.c
  * Description        : This file provides code for the configuration
  *                      of the USART instances.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "lora.h"
#include "bsp.h"


#define DEBUG_LORA_MAP_UART5   0


static __INLINE void lora_io_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	HAL_GPIO_WritePin(LORA_PWREN_GPIO_Port,  LORA_PWREN_Pin,  GPIO_PIN_RESET);
	HAL_GPIO_WritePin(LORA_RESET_GPIO_Port,  LORA_RESET_Pin,  GPIO_PIN_RESET);
	HAL_GPIO_WritePin(LORA_RELOAD_GPIO_Port, LORA_RELOAD_Pin, GPIO_PIN_SET);
	
	/*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin   = LORA_PWREN_Pin;
  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull  = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LORA_PWREN_GPIO_Port, &GPIO_InitStruct);
	
  GPIO_InitStruct.Pin   = LORA_RELOAD_Pin|LORA_RESET_Pin;
  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull  = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	
	GPIO_InitStruct.Pin  = LORA_HOSTWK_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(LORA_HOSTWK_GPIO_Port, &GPIO_InitStruct);
	
	NVIC_SetPriority(EXTI4_15_IRQn, 3);
  NVIC_EnableIRQ(EXTI4_15_IRQn);
	
	__HAL_GPIO_EXTI_CLEAR_IT(LORA_HOSTWK_Pin);
}

/* USART3 init function */
static __INLINE void lora_uart_init(void)
{
  LL_USART_InitTypeDef USART_InitStruct = {0};
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
	LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOD);
  
  /**USART2 GPIO Configuration
  PD5   ------> USART2_TX
  PD6   ------> USART2_RX
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_5;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
  LL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_6;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
  LL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /* USART1 interrupt Init */
  NVIC_SetPriority(USART2_IRQn, 3);
  NVIC_EnableIRQ(USART2_IRQn);

  USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
  USART_InitStruct.BaudRate = 115200;
  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
  LL_USART_Init(USART2, &USART_InitStruct);
	
	LL_USART_ConfigAsyncMode(USART2);
	
  LL_USART_SetTXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);
  LL_USART_SetRXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);
  LL_USART_DisableFIFO(USART2);
	
  LL_USART_SetRxTimeout(USART2, 2304u);                         /* (1/115200)  50ms */
  LL_USART_EnableRxTimeout(USART2);
	
	LL_USART_SetDEAssertionTime(USART2, 31);                      /* 485???????? */
  LL_USART_SetDEDeassertionTime(USART2, 31);                    /* 485???????? */
  LL_USART_SetDESignalPolarity(USART2, LL_USART_DE_POLARITY_HIGH);
  LL_USART_DisableDEMode(USART2);
	
	LL_USART_DisableDMADeactOnRxErr(USART2);
  
  LL_USART_DisableInStopMode(USART2);                           /* ????????mcu: disable */
  
	LL_USART_SetWakeUpMethod(USART2, LL_USART_WAKEUP_IDLELINE);   /* uart????:????????? */
  LL_USART_DisableMuteMode(USART2);                             /* ??uart????,????????,??????,?????????? */
  
  LL_USART_SetTXRXSwap(USART2, LL_USART_TXRX_STANDARD);         /* tx rx????:?? */
  
  LL_USART_SetTXPinLevel(USART2, LL_USART_TXPIN_LEVEL_STANDARD);
  LL_USART_SetRXPinLevel(USART2, LL_USART_RXPIN_LEVEL_STANDARD);
  LL_USART_SetBinaryDataLogic(USART2, LL_USART_BINARY_LOGIC_POSITIVE);
  
  LL_USART_DisableAutoBaudRate(USART2);
  LL_USART_DisableOneBitSamp(USART2);                           /* ??????,??3??? */
  
  LL_USART_DisableHalfDuplex(USART2);
  
  LL_USART_EnableIT_RXNE_RXFNE(USART2);
  LL_USART_EnableIT_RTO(USART2);
	
  LL_USART_Enable(USART2);

  /* Polling USART1 initialisation */
  while((!(LL_USART_IsActiveFlag_TEACK(USART2))) || (!(LL_USART_IsActiveFlag_REACK(USART2))))
  {
  }
	
	LL_USART_ClearFlag_RTO(USART2);
}

void LoRa_UartSendStr(const char *buf)
{
	uint32_t i;
  
	for(i=0; buf[i]!='\0'; i++)
	{
    USART2->TDR = (buf[i]& (uint16_t)0x01FFU);
    while(READ_BIT(USART2->ISR, USART_ISR_TXE_TXFNF) != (USART_ISR_TXE_TXFNF));

#if DEBUG_LORA_MAP_UART5 > 1
		USART1->TDR = (buf[i] & (uint16_t)0x01ffU);
		while(READ_BIT(USART1->ISR, USART_ISR_TXE_TXFNF) != (USART_ISR_TXE_TXFNF));
#endif
	}
  
  while(READ_BIT(USART2->ISR, USART_ISR_TC) != (USART_ISR_TC));
}

void LoRa_UartSendBuf(const uint8_t *buf, uint32_t len)
{
	uint32_t i;
	for(i=0; i<len; i++)
	{
#if DEBUG_LORA_MAP_UART5 > 1
		USART1->TDR = (buf[i] & (uint16_t)0x01ffU);
		while(READ_BIT(USART1->ISR, USART_ISR_TXE_TXFNF) != (USART_ISR_TXE_TXFNF)){};
#endif
		
    USART2->TDR = (buf[i] & (uint16_t)0x01ffU);
    while(READ_BIT(USART2->ISR, USART_ISR_TXE_TXFNF) != (USART_ISR_TXE_TXFNF));
	}
  
  while(READ_BIT(USART2->ISR, USART_ISR_TC) != (USART_ISR_TC));
}

void LoRa_BspInit(void)
{
	lora_io_init();
	lora_uart_init();
}

/**
  * @brief This function handles USART2 global interrupt.
  */
void USART2_IRQHandler(void)
{	
	if(READ_BIT(USART2->ISR, USART_ISR_RXNE_RXFNE) != 0)
	{
#if DEBUG_LORA_MAP_UART5 > 0
		USART1->TDR = USART2->RDR;
		while(READ_BIT(USART1->ISR, USART_ISR_TXE_TXFNF) != (USART_ISR_TXE_TXFNF));
#endif
    
		LoRa_RecvIsr.buf[LoRa_RecvIsr.count++] = USART2->RDR;
		if(LoRa_RecvIsr.count >= LORA_BUF_MAXLEN)
		{
			if(LoRaRecv_qhd != NULL)   /* make sure tasks are created */
			{
				xQueueSendFromISR(LoRaRecv_qhd, &LoRa_RecvIsr, NULL);
				LoRa_RecvIsr.count = 0;
			}
		}
	}
  
  if(READ_BIT(USART2->ISR, USART_ISR_RTOF) != 0)
	{
    if(LoRaRecv_qhd != NULL)   /* make sure tasks are created */
		{
      LL_USART_ClearFlag_RTO(USART2);
      
			xQueueSendFromISR(LoRaRecv_qhd, &LoRa_RecvIsr, NULL);
			LoRa_RecvIsr.count = 0;
		}
  }
  
  if(READ_BIT(USART2->ISR, USART_ISR_ORE) != 0)
	{
    LL_USART_ClearFlag_ORE(USART2);
  }
}


void EXTI4_15_IRQHandler(void)
{
	if(__HAL_GPIO_EXTI_GET_RISING_IT(LORA_HOSTWK_Pin) != RESET)
  {
    __HAL_GPIO_EXTI_CLEAR_RISING_IT(LORA_HOSTWK_Pin);
    
    LED1(0);
  }
  
  if(__HAL_GPIO_EXTI_GET_FALLING_IT(LORA_HOSTWK_Pin) != RESET)
  {
    __HAL_GPIO_EXTI_CLEAR_FALLING_IT(LORA_HOSTWK_Pin);
    
    LED1(1);
  }
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
